package drds.plus.executor.function.scalar.datatime;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.function.scalar.ScalarFunction;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.type.Type;

import java.text.SimpleDateFormat;

/**
 * The extract() function uses the same kinds of unit specifiers setAliasAndSetNeedBuild
 * DATE_ADD() or DATE_SUB(), but extracts parts from the date rather than
 * performing date arithmetic.
 *
 * <pre>
 * mysql> SELECT extract(YEAR FROM '2009-07-02');
 *        -> 2009
 * mysql> SELECT extract(YEAR_MONTH FROM '2009-07-02 01:02:03');
 *        -> 200907
 * mysql> SELECT extract(DAY_MINUTE FROM '2009-07-02 01:02:03');
 *        -> 20102
 * mysql> SELECT extract(MICROSECOND
 *     ->                FROM '2003-01-02 10:30:00.000123');
 *         -> 123
 * </pre>
 *
 * @author jianghang 2014-4-17 上午11:41:12
 * @since 5.0.7
 */
public class Extract extends ScalarFunction {

    @SuppressWarnings("deprecation")

    public Object compute(ExecuteContext executeContext, Object[] args) {
        for (Object arg : args) {
            if (Utils.isNull(arg)) {
                return null;
            }
        }

        String interval = Type.StringType.convert(args[0]);
        Interval.Interval_Unit unit = Interval.Interval_Unit.valueOf(interval);
        java.sql.Timestamp timestamp = Type.TimestampType.convert(args[1]);
        if (unit == Interval.Interval_Unit.QUARTER) {
            return timestamp.getMonth() / 3 + 1;
        } else {
            SimpleDateFormat format = new SimpleDateFormat(unit.format);
            String value = format.format(timestamp);
            Type type = getReturnType();
            return type.convert(value);
        }
    }

    public Type getReturnType() {
        return Type.LongType;
    }

    public String[] getFunctionNames() {
        return new String[]{"extract"};
    }
}
